<template>
  <el-upload
    accept=".mp3, .m4a, .aac, .mp4, .m4v"
    :before-upload="beforeUpload"
    :http-request="upload"
    :show-file-list="false"
    :disabled="disabled"
    style="display: inline-block"
    class="m-x-12"
  >
    <el-tooltip placement="bottom">
      <template #content>
        可上传本地录音录像，支持上传的
        <br />音频格式为：mp3、m4a、aac
        <br />
        视频格式为：mp4、m4v
      </template>
      <el-button type="primary" style="font-size: 12px" :disabled="disabled">
        上传录音录像
      </el-button>
    </el-tooltip>
  </el-upload>
  <el-dialog
    v-model="dialogVisible"
    :fullscreen="true"
    :show-close="false"
    custom-class="dispute-upload-dialog"
  >
    <div class="center">
      <div class="fz-18 ellipsis">正在上传：{{ fileData.name }}</div>
      <el-progress
        :text-inside="true"
        :stroke-width="16"
        :percentage="percentage"
      />
      <el-button style="margin-top: 10px" @click="cancel">取消上传</el-button>
    </div>
  </el-dialog>
</template>

<script setup>
import { getToken } from "@/utils/auth";
import axios from "axios";
const { proxy } = getCurrentInstance();
const emit = defineEmits(["videoUrl"]);
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const props = defineProps({
  modelValue: [String, Object, Array],
});
const beforeUpload = (file) => {
  const mimeTypes = [
    "audio/mpeg",
    "audio/x-m4a",
    "audio/aac",
    "video/mp4",
    "video/x-m4v",
  ];
  if (!mimeTypes.includes(file.type)) {
    proxy.$modal.msgError({
      type: "error",
      message: "只能上传 MP3、M4A、AAC、MP4、M4V 格式的文件",
      duration: 6000,
    });
    return false;
  }
  if (file.size / 1024 / 1024 / 1024 > 1.5) {
    proxy.$modal.msgError("文件大小不能超过 1.5G");
    proxy.$modal.msgError({
      type: "error",
      message: "文件大小不能超过 1.5G",
      duration: 6000,
    });
    return false;
  }
  return true;
};

const dialogVisible = ref(false);
const cancelUpload = ref(false);
let controller = null;
const chunkSize = 5 * 1024 * 1024; // 切片大小1M
const percentage = ref(0);
const fileData = ref({
  name: "",
  size: 0,
  type: "",
  suffix: "",
  md5: "",
});
const cancel = () => {
  const formData = new FormData();
  formData.append("name", fileData.value.name);
  formData.append("md5", fileData.value.md5);
  dialogVisible.value = false;
  cancelUpload.value = true;
  controller?.abort();
  axios.post(baseUrl + "/system/oss/endUpload", formData,{
    headers: {
      "Content-Type": "multipart/form-data",
      Authorization: "Bearer " + getToken(),
    },
  }).then(() => {
    proxy.$modal.msgSuccess("取消上传");
  });
};

let counter = 0;
const getFileMd5 = () => {
  let guid = (+new Date()).toString(32);
  for (let i = 0; i < 5; i++) {
    guid += Math.floor(Math.random() * 65535).toString(32);
  }
  return "wu_" + guid + (counter++).toString(32);
};

const updateUrl = (fileUrl) => {
  console.log("fileUrl===>>", fileUrl);
  axios.post("saveUrl", {
    fileName: fileData.value.name,
    fileUrl,
  });
};

// 上传切片
const uploadChunkFile = async (i, fileObj, chunkCount) => {
  console.log(i, fileObj);
  const start = i * chunkSize;
  const end = Math.min(fileData.value.size, start + chunkSize);
  console.log(start, end);
  const chunkFile = fileObj.slice(start, end);
  console.log("chunkFile=>", chunkFile);
  const formData = new FormData();
  formData.append("encrypt", "true");
  formData.append("name", fileData.value.name);
  formData.append("md5", fileData.value.md5);
  formData.append("file", chunkFile, String(i + 1));
  formData.append("size", fileObj.size);
  formData.append("chunk", i);
  formData.append("chunks", chunkCount);

  controller = new AbortController();
  return await axios
    .post(baseUrl + "/system/oss/uploadBigFile", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + getToken(),
      },
      onUploadProgress: (data) => {
        percentage.value = Number(
          (
            (Math.min(fileData.value.size, start + data.loaded) /
              fileData.value.size) *
            100
          ).toFixed(2)
        );
      },
      signal: controller.signal,
    })
    .then((res) => {
      console.log(res);
      return res;
      updateUrl(res.data);
    });
};

// 计算切片数量
const batchUpload = async (fileObj) => {
  percentage.value = 0;
  dialogVisible.value = true;
  cancelUpload.value = false;
  const chunkCount = Math.ceil(fileData.value.size / chunkSize); // 切片数量
  console.log("切片数量", chunkCount);
  fileData.value.md5 = getFileMd5(); // 文件唯一标识
  for (let i = 0; i < chunkCount; i++) {
    if (cancelUpload.value) return;
    const res = await uploadChunkFile(i, fileObj, chunkCount);
    console.log(res, "分割线--------------", fileData.value);

    if (res && res.data.code === 200 && res.data.data.url) {
      proxy.$modal.msgSuccess({
        message: `${fileData.value.name}上传成功`,
        title: "提示",
      });
      dialogVisible.value = false;
      emit("update:modelValue", res.data.data.url);
      emit("videoUrl", res.data.data.url);
    } else if (res && res.data.code !== 200) {
      dialogVisible.value = false;
      proxy.$modal.msgError({
        message: `${fileData.value.name}上传失败`,
        title: "提示",
      });
    }

    // if (i === chunkCount - 1) {
    //   console.log("循环上传");
    //   return;
    //   setTimeout(() => {
    //     dialogVisible.value = false;
    //     proxy.$modal.msgSuccess({
    //       message: `${fileData.value.name}上传成功`,
    //       title: "提示",
    //     });
    //     axios
    //       .post("tem/oss/uploadTest", {
    //         folder: fileData.value.md5,
    //       })
    //       .then((res) => {
    //         console.log(res);
    //         return;
    //         updateUrl(res.data);
    //       });
    //   }, 500);
    // }
  }
};

// 选择文件
const disabled = ref(false);
const upload = async (file) => {
  console.log(file);
  const fileObj = file.file;
  const formData = new FormData();
  formData.append("file", file.file);
  const nameList = fileObj.name.split(".");
  fileData.value.name = fileObj.name;
  fileData.value.size = fileObj.size;
  fileData.value.type = fileObj.type;
  fileData.value.suffix = nameList[nameList.length - 1];

  console.log("比较大小", chunkSize, fileData.value.size);
  if (chunkSize > fileData.value.size) {
    proxy.$modal.loading("正在上传文件，请稍候...");
    // 说明是小文件只有1M
    disabled.value = true;
    axios
      .post(baseUrl + "/system/oss/upload", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
          Authorization: "Bearer " + getToken(),
        },
      })
      .then((res) => {
        proxy.$modal.msgSuccess({
          message: `${fileData.value.name}上传成功`,
          title: "提示",
        });
        proxy.$modal.closeLoading();
        emit("update:modelValue", res.data.data.url);
        emit("videoUrl", res.data.data.url);
      })
      .catch(() => {
        proxy.$modal.msgError({
          message: `${fileData.value.name}上传失败`,
          title: "提示",
        });
        proxy.$modal.closeLoading();
      })
      .finally(() => (disabled.value = false));
    return;
  }
  batchUpload(fileObj);
};
</script>

<style lang="scss">
.dispute-upload-dialog {
  background: none;
}
</style>

<style lang="scss" scoped>
.center {
  color: #fff;
  width: 50%;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
